テスト実行時にNo route matches GET "/packs/js/application-xxx.jsのエラーが出たときの対処
状態
テスト実行時に以下エラーが発生
code:_
Error:
User::CompaniesTest#test_show_graduate_belonging_to_each_company:
ActionController::RoutingError: No route matches GET "/packs/js/application-6bbbed8ed4f200d94055.js"
/Users/karlley/.rbenv/versions/3.1.6/lib/ruby/gems/3.1.0/gems/actionpack-6.1.7.10/lib/action_dispatch/middleware/debug_exceptions.rb:33:in `call'
...
原因
テスト実行時に古いdigestのコンパイル後のファイルを参照していたため
Rails は manifest.json に記録された digest 付きファイル名を参照する
manifest.json が古い状態で残っていたため、存在しないファイルを参照していた
対策
古いコンパイル済みファイルと manifest を削除する
削除後、テスト実行時に自動で再コンパイルされるため、正しい digest ファイルを参照するようになる
code: (sh)
bin/rails webpacker:clobber
以下のファイルが削除される
code:_
public/packs/
public/packs-test/
tmp/cache/webpacker/
manifest.json
digestとは?
ファイル内容から計算したハッシュ値 のこと
Rails や Webpacker ではアセット(JS, CSS, 画像など)に digest を付与したファイル名 を生成する
code:_
application.js
application-6bbbed8ed4f200d94055.js ← digest 付き
なぜdigestを使うのか?
1. キャッシュ破棄のため
ブラウザは同じファイル名ならキャッシュを使ってしまう
ファイルを更新しても application.js のままだと古いキャッシュを読み続けてしまう
digest 付きにすると 中身が変わればファイル名も変わる ため、常に最新を取得できる
1. ファイルの一意性を保証する
digest はファイル内容を元に計算されるので、衝突が起きにくい
そのため「この digest ファイル名ならこの内容」と保証できる
Rails / Webpacker における動作
bin/rails assets:precompile やbin/rails webpacker:compile をするとdigest付きファイルが生成される
manifest.json に「論理名 → digest 付きファイル名」の対応が記録される
例) public/packs/manifest.json
code:_
{
"application.js": "/packs/js/application-6bbbed8ed4f200d94055.js",
"styles.css": "/packs/css/styles-2c8b3c9a4f.css"
}
Rails側はjavascript_pack_tag 'application' のように論理名を指定するだけでmanifest.json を参照して正しいdigest付きファイルを読み込む
#Rails
#Webpacker